package service

import (
	"context"
	"fmt"
	"iris-wms/apps/admin/middleware/logsink"
	"iris-wms/apps/admin/web/dto/din"
	"iris-wms/apps/admin/web/dto/dout"
	"iris-wms/common/model"
	"iris-wms/common/pkg/db"
	"iris-wms/common/pkg/db/dao"

	"github.com/kataras/golog"
	"gorm.io/gorm"
)

var _ AdminPolicyService = (*adminPolicyService)(nil)

type AdminPolicyService interface {
	DeleteByIdList([]uint) error
	GetTable(din.AdminPolicyTableIn) ([]*dout.AdminPolicyOut, int64, error)
	GetList() ([]*dout.AdminPolicyOut, error)
	Log(din.AdminPolicyOfLogIn) error
}

func NewAdminPolicyService() *adminPolicyService {
	return &adminPolicyService{}
}

type adminPolicyService struct{}

func (impl *adminPolicyService) DeleteByIdList(idList []uint) (err error) {
	var policyList = make([]*model.AdminPolicy, 0)
	if len(idList) > 0 {
		if err = db.GDB1.Find(&policyList, "id in ?", idList).Error; err != nil {
			return
		}
	}
	if err = db.GDB1.Transaction(func(tx *gorm.DB) error {
		if err = tx.Delete(&model.AdminPolicy{}, "id in ?", idList).Error; err != nil {
			return err
		}
		if err = tx.Delete(&model.AdminRolePolicy{}, "pid in ?", idList).Error; err != nil {
			return err
		}
		for _, v := range policyList {
			if err = tx.Delete(&model.AdminRule{},
				"ptype='p' AND v2=? AND v3=? AND v4=?", v.V2, v.V3, v.V4).Error; err != nil {
				return err
			}
		}
		return nil
	}); err != nil {
		return
	}
	return
}

func (impl *adminPolicyService) GetTable(in din.AdminPolicyTableIn) (rows []*dout.AdminPolicyOut, total int64, err error) {
	q := dao.Use(db.GDB1).AdminPolicyOut
	do := q.WithContext(context.Background())

	if in.Word != "" {
		word := fmt.Sprintf("%%%s%%", in.Word)
		do = do.
			Where(do.Where(q.GroupName.Like(word)).
				Or(q.Name.Like(word)).
				Or(q.V2.Like(word)).
				Or(q.V3.Like(word)))
	}
	rows, total, err = do.FindByPage(in.Offset(), in.PageSize)
	return
}

func (impl *adminPolicyService) GetList() (rows []*dout.AdminPolicyOut, err error) {
	m := dao.Use(db.GDB1).AdminPolicyOut
	do := m.WithContext(context.Background())

	rows, err = do.Order(m.GroupName).Find()
	return
}

func (impl *adminPolicyService) Log(in din.AdminPolicyOfLogIn) (err error) {
	if len(in.IdList) > 0 {
		if err = db.GDB1.Model(&model.AdminPolicy{}).
			Where("id in ?", in.IdList).Update("logable", in.Operation).Error; err != nil {
			return
		}
		if err := db.GDB1.Find(&logsink.GPolicyLogList, "logable=TRUE").Error; err != nil {
			golog.Error("刷新policy log 缓存失败,错误=%v", err)
		}
	}
	return
}
